﻿/*******************************************************************************
 * Copyright © 2016 CKS.Core.Framework 版权所有
 * Author: Sunny
 * Description: Framework快速开发平台
 * 
*********************************************************************************/
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Reflection;

namespace CKS.Core.Framework
{
    public static class ExtList
    {
        /// <summary>
        /// 获取表里某页的数据
        /// </summary>
        /// <param name="data">表数据</param>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">分页大小</param>
        /// <param name="allPage">返回总页数</param>
        /// <returns>返回当页表数据</returns>
        public static List<T> GetPage<T>(this List<T> data, int pageIndex, int pageSize, out int allPage)
        {
            allPage = 1;
            return null;
        }
        /// <summary>
        /// IList转成List<T>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static List<T> IListToList<T>(IList list)
        {
            T[] array = new T[list.Count];
            list.CopyTo(array, 0);
            return new List<T>(array);
        }

        public static DataTable ToDataTable<T>(this IList<T> data)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable dt = new DataTable();
            for (int i = 0; i < properties.Count; i++)
            {
                PropertyDescriptor property = properties[i];
                dt.Columns.Add(property.Name, property.PropertyType);
            }
            object[] values = new object[properties.Count];
            foreach (T item in data)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = properties[i].GetValue(item);
                }
                dt.Rows.Add(values);
            }
            return dt;
        }

        public static List<TEntity> ToList<TEntity>(this DataTable dt)
        {
            if (dt == null)
            {
                return new List<TEntity>();
            }
            List<TEntity> list = new List<TEntity>();
            foreach (DataRow row in dt.Rows)
            {
                list.Add(ToEntity<TEntity>(row));
            }
            return list;
        }

        public static TEntity ToEntity<TEntity>(this DataRow row)
        {
            if (row == null)
            {
                return default(TEntity);
            }
            Type objType = typeof(TEntity);
            return (TEntity)ConvertRowToObject(objType, row);
        }
        /// <summary>
        /// 转换DataRow到实体对象
        /// </summary>
        /// <param name="objType"></param>
        /// <param name="row"></param>
        /// <returns></returns>
        public static object ConvertRowToObject(Type objType, DataRow row)
        {
            if (row == null)
            {
                return null;
            }
            DataTable table = row.Table;
            object target = Activator.CreateInstance(objType);
            foreach (DataColumn column in table.Columns)
            {
                PropertyInfo property = objType.GetProperty(column.ColumnName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                if (property == null)
                {
                    //throw new PropertyNotFoundException( column.ColumnName );
                    continue;
                }
                Type propertyType = property.PropertyType;
                object obj3 = null;
                bool flag = true;
                try
                {
                    obj3 = TypeHelper.ChangeType(propertyType, row[column.ColumnName]);
                }
                catch
                {
                    flag = false;
                }
                if (flag)
                {
                    object[] args = new object[] { obj3 };
                    objType.InvokeMember(column.ColumnName, BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase, null, target, args);
                }
            }
            return target;
        }

        /// <summary>
        /// 转换实体到另一个实体对象
        /// </summary>
        /// <typeparam name="T">新的类型</typeparam>
        /// <param name="obj">需要转换的数据</param>
        /// <returns></returns>
        public static T Convert<T>(this object obj)
        {
            if (obj == null)
            {
                return default(T);
            }
            var objType = typeof(T);
            object target = Activator.CreateInstance(objType);
            var sourceType =obj.GetType();
            var properties =sourceType.GetProperties();
            foreach (var item in properties)
            {
                //目标类型中获取属性字段
                PropertyInfo property = objType.GetProperty(item.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
                if (property == null)
                {
                    //throw new PropertyNotFoundException( column.ColumnName );
                    continue;
                }
                

                Type propertyType = property.PropertyType;
                object obj3 = null;
                bool flag = true;
                try
                {
                    obj3 = TypeHelper.ChangeType(propertyType, item.GetValue(obj));
                }
                catch
                {
                    flag = false;
                }
                if (flag&&property.CanWrite)
                {
                    object[] args = new object[] { obj3 };
                    objType.InvokeMember(item.Name, BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase, null, target, args);
                }
            }
            return (T)target;
        }

        /// <summary>
        /// 转换为安全的线程集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static ConcurrentBag<T> ToConcurrentBag<T>(this IEnumerable<T> source)
        {
            return  new ConcurrentBag<T>(source);
        }
    }

    public class TypeHelper
    {
        /// <summary>
        /// 调整对象类型
        /// </summary>
        /// <param name="targetType"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public static object ChangeType(Type targetType, object val)
        {
            if (val == null)
            {
                return null;
            }
            if (targetType == val.GetType())
            {
                return val;
            }
            if (targetType == typeof(bool))
            {
                if (val.ToString() == "0")
                {
                    return false;
                }
                if (val.ToString() == "1")
                {
                    return true;
                }
            }
            if (targetType.IsEnum)
            {
                int result = 0;
                if (!int.TryParse(val.ToString(), out result))
                {
                    return Enum.Parse(targetType, val.ToString());
                }
                return val;
            }
            if (targetType == typeof(Type))
            {
                return GetType(val.ToString());
            }
            return Convert.ChangeType(val, targetType);
        }

        public static string GetClassSimpleName(Type t)
        {
            string[] strArray = t.ToString().Split(new char[] { '.' });
            return strArray[strArray.Length - 1].ToString();
        }

        public static string GetDefaultValue(Type destType)
        {
            if (IsNumbericType(destType))
            {
                return "0";
            }
            if (destType == typeof(string))
            {
                return "\"\"";
            }
            if (destType == typeof(bool))
            {
                return "false";
            }
            if (destType == typeof(DateTime))
            {
                return "DateTime.Now";
            }
            if (destType == typeof(Guid))
            {
                return "System.Guid.NewGuid()";
            }
            if (destType == typeof(TimeSpan))
            {
                return "System.TimeSpan.Zero";
            }
            return "null";
        }

        /// <summary>
        /// 获取类型
        /// </summary>
        /// <param name="typeAndAssName"></param>
        /// <returns></returns>
        public static Type GetType(string typeAndAssName)
        {
            string[] strArray = typeAndAssName.Split(new char[] { ',' });
            if (strArray.Length < 2)
            {
                return Type.GetType(typeAndAssName);
            }
            return GetType(strArray[0].Trim(), strArray[1].Trim());
        }
        /// <summary>
        /// 获取类型
        /// </summary>
        /// <param name="typeFullName"></param>
        /// <param name="assemblyName"></param>
        /// <returns></returns>
        public static Type GetType(string typeFullName, string assemblyName)
        {
            if (assemblyName == null)
            {
                return Type.GetType(typeFullName);
            }
            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (Assembly assembly in assemblies)
            {
                if (assembly.FullName.Split(new char[] { ',' })[0].Trim() == assemblyName.Trim())
                {
                    return assembly.GetType(typeFullName);
                }
            }
            Assembly assembly2 = Assembly.Load(assemblyName);
            if (assembly2 != null)
            {
                return assembly2.GetType(typeFullName);
            }
            return null;
        }

        public static Type GetTypeByRegularName(string regularName)
        {
            return GetType(regularName);
        }

        public static string GetTypeRegularName(Type destType)
        {
            string str = destType.Assembly.FullName.Split(new char[] { ',' })[0];
            return string.Format("{0},{1}", destType.ToString(), str);
        }

        public static string GetTypeRegularNameOf(object obj)
        {
            return GetTypeRegularName(obj.GetType());
        }

        public static bool IsFixLength(Type destDataType)
        {
            return (IsNumbericType(destDataType) || ((destDataType == typeof(byte[])) || ((destDataType == typeof(DateTime)) || (destDataType == typeof(bool)))));
        }

        public static bool IsNumbericType(Type destDataType)
        {
            return ((((((destDataType == typeof(int)) || (destDataType == typeof(uint))) || ((destDataType == typeof(double)) || (destDataType == typeof(short)))) || (((destDataType == typeof(ushort)) || (destDataType == typeof(decimal))) || ((destDataType == typeof(long)) || (destDataType == typeof(ulong))))) || ((destDataType == typeof(float)) || (destDataType == typeof(byte)))) || (destDataType == typeof(sbyte)));
        }

        public static bool IsSimpleType(Type t)
        {
            return (IsNumbericType(t) || ((t == typeof(char)) || ((t == typeof(string)) || ((t == typeof(bool)) || ((t == typeof(DateTime)) || ((t == typeof(Type)) || t.IsEnum))))));
        }


        

    }

}
